/*
 * Includes
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <minix/endpoint.h>
#include <minix/syslib.h>
#include <sys/types.h>
#include <sys/stat.h>

#define NUMBER_OF_STATES	3

enum states {
	STATE_SPEED250, STATE_CURVE, STATE_ERROR
};
char *mapState(char *, enum states);
/*
 * Runs the program
 */
int main(int argc, char* argv[]) {
	enum states state;
	enum states nextState[NUMBER_OF_STATES];
	long int cmd;
	char *speed;
	message *m;
	int errno;
	int comEndpoint;
	register message *msgptr;
	int status;

	/*Declare alphabet*/
	char actions[50] = "s.w.250 p.c.1 STATE_ERROR ;";
	/*Set init state*/
	state = STATE_CURVE;
	/*Send init message to pm and receive com endpoint*/
	msgptr->m_type = INIT_PROC;
	status = _sendrec(PM_PROC_NR, msgptr);
	if (status != 0) {
		printf("Error in sendrec process\n");
	}
	/* Get endpoint from com */
	switch (msgptr->m_type) {
	case SEND_ENDPOINT: comEndpoint = msgptr->RT_DRIVER_ENDPT;break;
	default:printf("handle process reply: unknown reply type: %d\n",msgptr->m_type);break;
	}

	/*Send alphabet to com driver*/
	msgptr->m_type = INIT_PROC;
	msgptr->RT_PID = getpid();
	msgptr->PROC_ACTIONS = &actions;
	status = _sendrec(comEndpoint, msgptr);
	if (status != 0) {
		printf("Error in sendrec process\n");
	}
	switch (msgptr->m_type) {
	case INIT_PROC: printf("Reply received from com driver\n");break;
	default: printf("handle process reply: unknown reply type: %d\n",msgptr->m_type);	}

	/*Do main task*/
	msgptr->m_type = ASK_FOR_GO;
	while (1) {
		/*Do a sleep for more to get more time to see what happends*/
		sleep(5);

		/*Ask to do perform an action to comdriver*/
		msgptr->m_type = ASK_FOR_GO;
		msgptr->RT_PID = getpid();
		/*What to do in different states*/
		switch (state) {
		case STATE_SPEED250: {
			/*Possible next states*/
			nextState[0] = STATE_CURVE;
			nextState[1] = STATE_ERROR;
			nextState[2] = STATE_ERROR;
			/*Set which action to ask a go for*/
			msgptr->PROC_ACTIONS = mapState(nextState[0], state);
			status = _sendrec(comEndpoint, msgptr);
			if (status != 0) {
				printf("Error in sendrec process\n");
			}
			/*Go to next state*/
			state = nextState[0];
		}
			break;
		case STATE_CURVE: {
			/*Possible next states*/
			nextState[0] = STATE_SPEED250;
			nextState[1] = STATE_ERROR;
			nextState[2] = STATE_ERROR;
			/*Set which action to ask a go for*/
			msgptr->PROC_ACTIONS = mapState(nextState[0], state);
			status = _sendrec(comEndpoint, msgptr);
			if (status != 0) {
				printf("Error in sendrec process\n");
			}
			/*Go to next state*/
			state = nextState[0];
		}
			break;
		default: {
			/*Possible next states*/
			state = STATE_ERROR;
			nextState[0] = STATE_CURVE;
			nextState[1] = STATE_ERROR;
			nextState[2] = STATE_ERROR;
			/*Set which action to ask a go for*/
			msgptr->PROC_ACTIONS = mapState(nextState[0], state);
			status = _sendrec(comEndpoint, msgptr);
			if (status != 0) {
				printf("Error in sendrec process\n");
			}
			/*Go to next state*/
			state = nextState[0];
		}
			break;
		}
	}
	return (msgptr->m_type);
}

char *mapState(char *action, enum states state) {
	/*See which string action belongs to which enum state*/
	switch (state) {
	case STATE_SPEED250:
		action = "s.w.250";
		break;
	case STATE_CURVE:
		action = "p.c.1";
		break;
	case STATE_ERROR:
		action = "STATE_ERROR";
		break;
	default:
		printf("No current state found!\n");
		break;
	}
	return action;
}

